package com.yoke.service.domain;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import com.yoke.system.log.SystemLog;
import com.yoke.util.FileUtil;
import com.yoke.util.HttpClientUtils;
import com.yoke.util.StringUtil;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jiangzeyin on 2017/5/11.
 */
@Service
public class DoMainServer extends DoMainBaseService {

    public List<String> listAll() throws IOException {
        List<String> company = getUrls(getBootPath() + "/domain_list.conf", "company");
        List<String> personal = getUrls(getBootPath() + "/domain_list.conf", "personal");
        List<String> all = new ArrayList<>();
        if (company != null)
            all.addAll(company);
        if (personal != null)
            all.addAll(personal);
        return all;
    }

    public JSONArray getDomainRList(String name) throws Exception {
        int id = getDomainId(name);
        if (id <= 1)
            return null;
        return getRecord(id);
    }

    private int getDomainId(String domainUrl) throws Exception {
        Map<String, String> stringMap = getDefault();
        String html = HttpClientUtils.sendHttpPost("https://dnsapi.cn/Domain.List", stringMap);
        //System.out.println(html);
        JSONObject jsonObject = JSONObject.parseObject(html);
        JSONObject status = jsonObject.getJSONObject("status");
        int code = status.getIntValue("code");
        if (code != 1)
            return -0;
        JSONArray domains = jsonObject.getJSONArray("domains");
        if (domains != null)
            for (int i = 0; i < domains.size(); i++) {
                JSONObject domain = domains.getJSONObject(i);
                String name = domain.getString("name");
                if (domainUrl.equals(name))
                    return domain.getIntValue("id");
            }
        return -1;
    }

    private JSONArray getRecord(int id) throws Exception {
        Map<String, String> stringMap = getDefault();
        stringMap.put("domain_id", id + "");
        String html = HttpClientUtils.sendHttpPost("https://dnsapi.cn/Record.List", stringMap);
        JSONObject jsonObject = JSONObject.parseObject(html);
        return jsonObject.getJSONArray("records");
    }

    public List<String> getUrls(String path, String tag) throws IOException {
        NgxConfig conf = NgxConfig.read(path);
        List<NgxEntry> personals = conf.findAll(NgxConfig.BLOCK, tag);
        List<String> personalUrl = new ArrayList<>();
        for (NgxEntry ngxEntry : personals) {
            if (ngxEntry instanceof NgxBlock) {
                NgxBlock block = (NgxBlock) ngxEntry;
                for (NgxEntry entry : block.getEntries()) {
                    NgxParam ngxParam = (NgxParam) entry;
                    personalUrl.add(ngxParam.getName());
                }
            }
        }
        return personalUrl;
    }

    public int update_domain_(String domain, String rId, String value) {
        Map<String, String> stringMap = getDefault();
        //domain_id=2317346&sub_domain=@&record_type=A&record_line_id=10%3D3&value=1.1.1.1'
        stringMap.put("domain", domain);
        stringMap.put("record_id", rId);
        String html;
        try {
            html = HttpClientUtils.sendHttpPost("https://dnsapi.cn/Record.Info", stringMap);
        } catch (Exception e) {
            SystemLog.ERROR().error("修改错误", e);
            return -1;
        }
        JSONObject jsonObject = JSONObject.parseObject(html);
        JSONObject status = jsonObject.getJSONObject("status");
        int code = status.getIntValue("code");
        if (code != 1)
            return code;
        JSONObject record = jsonObject.getJSONObject("record");
        if (record == null)
            return -2;
        String old_value = record.getString("value");
        if (value.equals(old_value))
            return 0;
        Map<String, String> hashMap = getDefault();
        //domain_id=2317346&sub_domain=@&record_type=A&record_line_id=10%3D3&value=1.1.1.1'
        hashMap.put("domain", domain);
        hashMap.put("record_id", rId);
        hashMap.put("record_line_id", record.getString("record_line_id"));
        hashMap.put("sub_domain", record.getString("sub_domain"));
        hashMap.put("record_type", record.getString("record_type"));
        hashMap.put("value", value);
        try {
            html = HttpClientUtils.sendHttpPost("https://dnsapi.cn/Record.Modify", hashMap);
        } catch (Exception e) {
            SystemLog.ERROR().error("修改错误", e);
            return -11;
        }
        jsonObject = JSONObject.parseObject(html);
        status = jsonObject.getJSONObject("status");
        code = status.getIntValue("code");
        if (code != 1)
            return code;
        try {
            updateLog(domain, record.getString("sub_domain"), value);
        } catch (IOException e) {
            SystemLog.ERROR().error("修改错误", e);
        }
        return 1;
    }

    public int create_domain_(String domain, String name, String value) {
        //DoMainControl doMainControl = SpringUtil.getBean(DoMainControl.class);
        int domainId;
        try {
            domainId = getDomainId(domain);
            if (domainId <= 0)
                return -1;
        } catch (Exception e) {
            SystemLog.ERROR().error("创建错误", e);
            return -2;
        }
        Map<String, String> stringMap = getDefault();
        //domain_id=2317346&sub_domain=@&record_type=A&record_line_id=10%3D3&value=1.1.1.1'
        stringMap.put("domain_id", domainId + "");
        stringMap.put("sub_domain", name);
        stringMap.put("record_type", "A");
        //stringMap.put("record_line", "默认");
        stringMap.put("record_line_id", "0");
        stringMap.put("value", value);
        String html;
        try {
            html = HttpClientUtils.sendHttpPost("https://dnsapi.cn/Record.Create", stringMap);
        } catch (Exception e) {
            SystemLog.ERROR().error("创建错误", e);
            return -3;
        }
        //System.out.println(html);
        JSONObject jsonObject = JSONObject.parseObject(html);
        JSONObject status = jsonObject.getJSONObject("status");
        int code = status.getIntValue("code");
        if (code != 1)
            return code;
        try {
            updateLog(domain, name, value);
        } catch (IOException e) {
            SystemLog.ERROR().error("创建错误", e);
        }
        return 1;
    }

    private void updateLog(String domain, String name, String ip) throws IOException {
        List<String> logs = domain_log(domain, name);
        if (logs != null)
            if (logs.contains(ip))
                return;
        File file = new File(getBootPath(), "domain/" + domain + "/" + name);
        FileUtil.appendFileContext(file.getPath(), ip + System.lineSeparator());
    }

    public List<String> domain_log(String domain, String name) throws IOException {
        File file = new File(getBootPath(), "domain/" + domain + "/" + name);
        if (!file.exists())
            return null;
        BufferedReader bufferedReader = null;
        List<String> list = new ArrayList<>();
        try {
            bufferedReader = new BufferedReader(new FileReader(file));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                if (StringUtil.IsEmpty(line))
                    continue;
                list.add(line);
            }
            return list;
        } finally {
            try {
                if (bufferedReader != null)
                    bufferedReader.close();
            } catch (IOException e) {
                SystemLog.ERROR().error("获取记录错误", e);
            }
        }
    }

}
